package com.hiyee.api.interceptor;

import com.hiyee.annotation.JwtVerify;
import com.hiyee.api.config.ThreadLocalHolder;
import com.hiyee.exception.GraceException;
import com.hiyee.pojo.auth.CustomerTokenInfo;
import com.hiyee.response.ResponseStatusEnum;
import com.hiyee.utils.JWTUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * jwt token 校验拦截器
 *
 * @author WangBin
 */
public class TokenVerifyInterceptor implements HandlerInterceptor {

    private final Logger logger = LoggerFactory.getLogger(TokenVerifyInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        logger.debug("[拦截器]校验token...");
        // 判断是否有注解
        boolean hasAnnotataion = handler.getClass().isAssignableFrom(HandlerMethod.class);
        if(!hasAnnotataion) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        // 是否有校验 token 的注解
        boolean hasAnnotation = handler.getClass().isAssignableFrom(HandlerMethod.class);
        if(!hasAnnotation) {
            return true;
        }
        JwtVerify jwtVerify = ((HandlerMethod)handler).getMethodAnnotation(JwtVerify.class);
        if(jwtVerify == null) {
            return true;
        }
        // 取 header 中的 Authorization 信息
        String token = JWTUtil.getHeaderToken(request);
        if(token == null) {
            GraceException.display(ResponseStatusEnum.AUTH_FORBIDDEN);
        }

        CustomerTokenInfo customerTokenInfo = JWTUtil.verify(token);
        if(customerTokenInfo.getCustomerId() == null) {
            GraceException.display(ResponseStatusEnum.AUTH_FORBIDDEN);
        }
        // 客户信息存入 localThread
        ThreadLocalHolder.set(customerTokenInfo);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求完成清除 localThread
        ThreadLocalHolder.remove();
    }
}
